package com.example.zipstream;

import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class ZipStreamDemo1 {
    public static void main(String[] args) throws IOException {

        /**
         * ZIP 文件是一种常见的压缩文件格式，广泛用于文件的压缩和归档。
         * ZipOutputStream 用于将数据压缩成 ZIP 格式，而 ZipInputStream 用于解压 ZIP 文件。
         * 两者都提供了方便的方式来处理 ZIP 文件内的多个条目（entry），而不仅仅是单个文件。
         */

        /**
         * getNextEntry()：读取下一个条目并返回该条目的 ZipEntry 对象。如果没有更多的条目，返回 null。
         * read(byte[] b, int off, int len)：读取当前条目的数据。
         * closeEntry()：结束当前条目，准备下一个条目的读取。
         * close()：关闭流。
         */

        /**
         * 解压缩流
         */

        //1.创建一个File表示要解压的压缩包
        File src = new File("zip/src.zip");
        //2.创建一个File表示解压的目的地
        File dest = new File("zip/");

        //3.调用方法解压缩
        unzip(src, dest);

    }

    /**
     * 解压缩
     *
     * @param src
     * @param dest
     * @throws IOException
     */
    public static void unzip(File src, File dest) throws IOException {
        /**
         * 解压的本质：将压缩包里面的每一个文件或者文件夹读取出来，按照层级拷贝到目的地中
         */
        //创建一个解压缩流用来读取压缩包中的数据
        ZipInputStream zis = new ZipInputStream(new FileInputStream(src));
        //获取压缩包中的每一个ZipEntry对象
        //表示当前压缩包中获取到的文件或文件夹
        ZipEntry ze = zis.getNextEntry();
        while (ze != null) {
            if (ze.isDirectory()) {
                //文件夹：在目的地dest处创建一个同样的文件夹
                File dir = new File(dest, ze.toString());
                dir.mkdirs();
            } else {
                //文件：读取压缩包中的文件，并将其存放在目的地dest文件夹中（按照层级目录进行存放）
                FileOutputStream fos = new FileOutputStream(new File(dest, ze.toString()));
                int read = zis.read();
                while (read != -1) {
                    //写到目的地
                    fos.write(read);
                    read = zis.read();
                }
                fos.close();
                //压缩包中的一个文件处理完毕
                zis.closeEntry();
            }
            ze = zis.getNextEntry();
        }
        zis.close();
    }

}
